//*********************************************************
//
//    Copyright (c) Microsoft. All rights reserved.
//    This code is licensed under the Apache License, Version 2.0.
//    THIS CODE IS PROVIDED *AS IS* WITHOUT WARRANTY OF
//    ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING ANY
//    IMPLIED WARRANTIES OF FITNESS FOR A PARTICULAR
//    PURPOSE, MERCHANTABILITY, OR NON-INFRINGEMENT.
//
//*********************************************************

namespace Microsoft.Research.ScientificWorkflow.TridentUtilities
{
    #region Using directives

    using System;
    using System.Windows;
    using System.Windows.Input;
    using System.Windows.Controls;
    using System.Windows.Media.Imaging;
    using System.Windows.Documents;

    #endregion

    /// <summary>
    /// Interaction logic for TridentMessageBox.xaml
    /// </summary>
    public sealed partial class TridentMsgBox : Window
    {
        /// <summary>
        /// Message box result.
        /// </summary>
        private MessageBoxResult messageBoxResult;

        /// <summary>
        /// Constructor.
        /// </summary>
        public TridentMsgBox()
        {
            InitializeComponent();

            if (Application.Current != null && Application.Current.MainWindow != null)
            {
                this.Owner = Application.Current.MainWindow;
            }
        }

        #region Public methods

        /// <summary>
        /// Shows a message.
        /// </summary>
        /// <param name="messageBoxText">
        /// Message to be shown.
        /// </param>
        /// <returns>
        /// Message box result.
        /// </returns>
        public MessageBoxResult ShowMessage(string messageBoxText)
        {
            this.SetMode(MessageBoxButton.OK, MessageBoxImage.Information, MessageBoxResult.None);
            this.txtBlkMessage.Text = messageBoxText;
            this.ShowDialog();

            return this.messageBoxResult;
        }

        /// <summary>
        /// Shows a message.
        /// </summary>
        /// <param name="messageBoxText">Message to be shown.</param>
        /// <param name="caption">Window caption.</param>
        /// <returns>
        /// Message box result.
        /// </returns>
        public MessageBoxResult ShowMessage(string messageBoxText, string caption)
        {
            this.SetMode(MessageBoxButton.OK, MessageBoxImage.Information, MessageBoxResult.None);
            this.txtBlkMessage.Text = messageBoxText;
            this.Title = caption;
            this.ShowDialog();

            return this.messageBoxResult;
        }

        /// <summary>
        /// Shows a message.
        /// </summary>
        /// <param name="owner">Messagebox owner.</param>
        /// <param name="messageBoxText">Message to be shown.</param>
        /// <returns>
        /// Message box result.
        /// </returns>
        public MessageBoxResult ShowMessage(Window owner, string messageBoxText)
        {
            this.SetMode(MessageBoxButton.OK, MessageBoxImage.Information, MessageBoxResult.None);
            this.txtBlkMessage.Text = messageBoxText;
            if (owner != null)
            {
                this.Owner = owner;
            }

            this.ShowDialog();
            return this.messageBoxResult;
        }

        /// <summary>
        /// Shows a message.
        /// </summary>
        /// <param name="messageBoxText">Message to be shown.</param>
        /// <param name="caption">Window caption.</param>
        /// <param name="button">Messagebox button</param>
        /// <returns>
        /// Message box result.
        /// </returns>
        public MessageBoxResult ShowMessage(string messageBoxText, string caption, MessageBoxButton button)
        {
            this.SetMode(button, MessageBoxImage.Information, MessageBoxResult.None);
            this.txtBlkMessage.Text = messageBoxText;
            this.Title = caption;
            this.ShowDialog();

            return this.messageBoxResult;
        }

        /// <summary>
        /// Shows a message.
        /// </summary>
        /// <param name="owner">Messagebox owner.</param>
        /// <param name="messageBoxText">Message to be shown.</param>
        /// <param name="caption">Window caption.</param>
        /// <returns>
        /// Message box result.
        /// </returns>
        public MessageBoxResult ShowMessage(Window owner, string messageBoxText, string caption)
        {
            this.SetMode(MessageBoxButton.OK, MessageBoxImage.Information, MessageBoxResult.None);
            this.txtBlkMessage.Text = messageBoxText;
            this.Title = caption;
            if (owner != null)
            {
                this.Owner = owner;
            }

            this.ShowDialog();
            return this.messageBoxResult;
        }

        /// <summary>
        /// Shows a message.
        /// </summary>
        /// <param name="messageBoxText">Message to be shown.</param>
        /// <param name="caption">Window caption.</param>
        /// <param name="button">Messagebox button</param>
        /// <param name="icon">Messagebox icon.</param>
        /// <returns>
        /// Message box result.
        /// </returns>
        public MessageBoxResult ShowMessage(string messageBoxText, string caption, MessageBoxButton button, MessageBoxImage icon)
        {
            this.SetMode(button, icon, MessageBoxResult.None);
            this.txtBlkMessage.Text = messageBoxText;
            this.Title = caption;
            this.ShowDialog();

            return this.messageBoxResult;
        }

        /// <summary>
        /// Shows a message.
        /// </summary>
        /// <param name="owner">Messagebox owner.</param>
        /// <param name="messageBoxText">Message to be shown.</param>
        /// <param name="caption">Window caption.</param>
        /// <param name="button">Messagebox button</param>
        /// <returns>
        /// Message box result.
        /// </returns>
        public MessageBoxResult ShowMessage(Window owner, string messageBoxText, string caption, MessageBoxButton button)
        {
            this.SetMode(button, MessageBoxImage.Information, MessageBoxResult.None);
            this.txtBlkMessage.Text = messageBoxText;
            this.Title = caption;
            if (owner != null)
            {
                this.Owner = owner;
            }

            this.ShowDialog();
            return this.messageBoxResult;
        }

        /// <summary>
        /// Shows a message.
        /// </summary>
        /// <param name="messageBoxText">Message to be shown.</param>
        /// <param name="caption">Window caption.</param>
        /// <param name="button">Messagebox button</param>
        /// <param name="icon">Messagebox icon.</param>
        /// <param name="defaultResult">Default result.</param>
        /// <returns>
        /// Message box result.
        /// </returns>
        public MessageBoxResult ShowMessage(string messageBoxText, string caption, MessageBoxButton button, MessageBoxImage icon, MessageBoxResult defaultResult)
        {
            this.SetMode(button, icon, defaultResult);
            this.txtBlkMessage.Text = messageBoxText;
            this.Title = caption;

            this.ShowDialog();
            return this.messageBoxResult;
        }

        /// <summary>
        /// Shows a message.
        /// </summary>
        /// <param name="owner">Messagebox owner.</param>
        /// <param name="messageBoxText">Message to be shown.</param>
        /// <param name="caption">Window caption.</param>
        /// <param name="button">Messagebox button</param>
        /// <param name="icon">Messagebox icon.</param>
        /// <returns>
        /// Message box result.
        /// </returns>
        public MessageBoxResult ShowMessage(Window owner, string messageBoxText, string caption, MessageBoxButton button, MessageBoxImage icon)
        {
            this.SetMode(button, icon, MessageBoxResult.None);
            this.txtBlkMessage.Text = messageBoxText;
            this.Title = caption;
            if (owner != null)
            {
                this.Owner = owner;
            }

            this.ShowDialog();
            return this.messageBoxResult;
        }
        
        /// <summary>
        /// Shows a message.
        /// </summary>
        /// <param name="owner">Messagebox owner.</param>
        /// <param name="messageBoxText">Message to be shown.</param>
        /// <param name="caption">Window caption.</param>
        /// <param name="button">Messagebox button</param>
        /// <param name="icon">Messagebox icon.</param>
        /// <param name="defaultResult">Default result.</param>
        /// <returns>
        /// Message box result.
        /// </returns>
        public MessageBoxResult ShowMessage(Window owner, string messageBoxText, string caption, MessageBoxButton button, MessageBoxImage icon, MessageBoxResult defaultResult)
        {
            this.SetMode(button, icon, defaultResult);
            this.txtBlkMessage.Text = messageBoxText;
            this.Title = caption;
            if (owner != null)
            {
                this.Owner = owner;
            }

            this.ShowDialog();
            return this.messageBoxResult;
        }

        #endregion

        /// <summary>
        /// Creates an instance of Button.
        /// </summary>
        /// <param name="content">
        /// Button text.
        /// </param>
        /// <returns>
        /// Button created.
        /// </returns>
        private static Button GetButton(string content)
        {
            Button button = new Button();
            button.Content = content;
            button.HorizontalAlignment = HorizontalAlignment.Right;
            button.VerticalAlignment = VerticalAlignment.Center;
            button.Width = 70;
            button.Margin = new Thickness(3, 0, 3, 0);

            return button;
        }

        /// <summary>
        /// Sets mode of the messagebox (Question, Warning, Error etc).
        /// </summary>
        /// <param name="buttonMode">
        /// Mode indicator.
        /// </param>
        /// <param name="buttonIcon">
        /// Icon to be shown.
        /// </param>
        /// <param name="buttonResult">
        /// Default result.
        /// </param>
        private void SetMode(MessageBoxButton buttonMode, MessageBoxImage buttonIcon, MessageBoxResult buttonResult)
        {
            if (buttonMode == MessageBoxButton.OK)
            {
                this.messageBoxResult = MessageBoxResult.OK;
                Button button = TridentMsgBox.GetButton("OK");
                button.IsDefault = true;
                button.IsCancel = true;
                button.Click += new RoutedEventHandler(this.OnOkClick);
                this.stkButtons.Children.Add(button);
                button.Focus();
            }
            else if (buttonMode == MessageBoxButton.OKCancel)
            {
                this.messageBoxResult = MessageBoxResult.Cancel;
                Button button = TridentMsgBox.GetButton("OK");
                button.IsDefault = true;
                button.Click += new RoutedEventHandler(this.OnOkClick);
                this.stkButtons.Children.Add(button);
                button.Focus();

                button = TridentMsgBox.GetButton("Cancel");
                button.IsCancel = true;
                button.Click += new RoutedEventHandler(this.OnCancelClick);
                this.stkButtons.Children.Add(button);
                if (buttonResult == MessageBoxResult.Cancel)
                {
                    button.Focus();
                }
            }
            else if (buttonMode == MessageBoxButton.YesNo)
            {
                this.messageBoxResult = MessageBoxResult.No;
                Button button = TridentMsgBox.GetButton("Yes");
                button.IsDefault = true;
                button.Click += new RoutedEventHandler(this.OnYesClick);
                this.stkButtons.Children.Add(button);
                button.Focus();

                button = TridentMsgBox.GetButton("No");
                button.IsCancel = true;
                button.Click += new RoutedEventHandler(this.OnNoClick);
                this.stkButtons.Children.Add(button);
                if (buttonResult == MessageBoxResult.No)
                {
                    button.Focus();
                }
            }
            else if (buttonMode == MessageBoxButton.YesNoCancel)
            {
                this.messageBoxResult = MessageBoxResult.Cancel;
                Button button = TridentMsgBox.GetButton("Yes");
                button.Click += new RoutedEventHandler(this.OnYesClick);
                this.stkButtons.Children.Add(button);
                button.Focus();

                button = TridentMsgBox.GetButton("No");
                button.Click += new RoutedEventHandler(this.OnNoClick);
                this.stkButtons.Children.Add(button);
                if (buttonResult == MessageBoxResult.No)
                {
                    button.Focus();
                }

                button = TridentMsgBox.GetButton("Cancel");
                button.IsCancel = true;
                button.Click += new RoutedEventHandler(this.OnCancelClick);
                this.stkButtons.Children.Add(button);
                if (buttonResult == MessageBoxResult.Cancel)
                {
                    button.Focus();
                }
            }

            // Set the icon.
            if (buttonIcon == MessageBoxImage.Error)
            {
                this.imgIcon.Source = new BitmapImage(new Uri(
                                    @"pack://Application:,,,/Microsoft.Research.ScientificWorkflow.TridentUtilities;component/Images/ScientificWorkflow/error.png", UriKind.RelativeOrAbsolute));
            }
            else if (buttonIcon == MessageBoxImage.Question)
            {
                this.imgIcon.Source = new BitmapImage(new Uri(
                    @"pack://Application:,,,/Microsoft.Research.ScientificWorkflow.TridentUtilities;component/Images/ScientificWorkflow/question.png", UriKind.RelativeOrAbsolute));
            }
            else if (buttonIcon == MessageBoxImage.Warning)
            {
                this.imgIcon.Source = new BitmapImage(new Uri(
                        @"pack://Application:,,,/Microsoft.Research.ScientificWorkflow.TridentUtilities;component/Images/ScientificWorkflow/warning.png", UriKind.RelativeOrAbsolute));
            }
            else
            {
                this.imgIcon.Source = new BitmapImage(new Uri(
                        @"pack://Application:,,,/Microsoft.Research.ScientificWorkflow.TridentUtilities;component/Images/ScientificWorkflow/information.png", UriKind.RelativeOrAbsolute));
            }
        }

        #region Event Handlers

        /// <summary>
        /// OnClick of the Ok button.
        /// </summary>
        /// <param name="sender">Ok button.</param>
        /// <param name="e">RoutedEventArgs.</param>
        private void OnOkClick(object sender, RoutedEventArgs e)
        {
            this.messageBoxResult = MessageBoxResult.OK;
            this.Close();
        }

        /// <summary>
        /// OnClick of the Cancel button.
        /// </summary>
        /// <param name="sender">Cancel button.</param>
        /// <param name="e">RoutedEventArgs.</param>
        private void OnCancelClick(object sender, RoutedEventArgs e)
        {
            this.messageBoxResult = MessageBoxResult.Cancel;
            this.Close();
        }

        /// <summary>
        /// OnClick of the yes button.
        /// </summary>
        /// <param name="sender">Yes button.</param>
        /// <param name="e">RoutedEventArgs.</param>
        private void OnYesClick(object sender, RoutedEventArgs e)
        {
            this.messageBoxResult = MessageBoxResult.Yes;
            this.Close();
        }

        /// <summary>
        /// OnClick of the no button.
        /// </summary>
        /// <param name="sender">No button.</param>
        /// <param name="e">RoutedEventArgs.</param>
        private void OnNoClick(object sender, RoutedEventArgs e)
        {
            this.messageBoxResult = MessageBoxResult.No;
            this.Close();
        }

        #endregion
    }
}
